#include "personvehiclepetDet.h"
#include "SdkCommon.h"

#define DEF_TAG             "Personvehiclepetdet"


#if CMAKE_USE_CHIP_AI && !CMAKE_PRODUCT_TEST

#define DEF_SDK_PERSON_DETECT_CHN              2
/* 竖屏图像90度旋转，所以宽和高的定义调换 */
int sensor_sub_width = DEF_PERSONVEHICLEPETDET_HEIGHT;
int sensor_sub_height = DEF_PERSONVEHICLEPETDET_WIDTH;
void *g_ChipSdk_model_bin = NULL;
IMPIVSInterface *g_Sdk_PersonInterface = NULL;

int ChipSdk_ivs_personvehiclepetdet_start(int grp_num, int chn_num, IMPIVSInterface **interface)
{
    //check ivs version
    //PERSONVEHICLEPETDET_VERSION_NUM defined in ivs_inf_personvehiclepetdet.h .
    uint32_t personvehiclepetdet_ver = personvehiclepetdet_get_version_info();
    if(personvehiclepetdet_ver != PERSONVEHICLEPETDET_VERSION_NUM)
    {
        printf("The version numbers of head file and lib do not match, head file version: %08x, lib version: %08x\n",
               PERSONVEHICLEPETDET_VERSION_NUM, personvehiclepetdet_ver);
        return -1;
    }
    //check ivs version
    int ret = 0;
    personvehiclepetdet_param_input_t param;

    memset(&param, 0, sizeof(personvehiclepetdet_param_input_t));
    param.frameInfo.width = sensor_sub_width;
    param.frameInfo.height = sensor_sub_height;

    param.skip_num = 0;      //skip num
    param.max_personvehiclepet_box = 3;
    param.sense = 5;
    param.detdist = 0;
    param.nmem_size = 11 * 1024 * 1024;
    param.switch_track = false;
    param.enable_move = false;
    param.open_move_filter = false;

    param.model_path = "/system/config/personvehiclepet_det.bin";
    FILE *fp = NULL;
    fp = fopen(param.model_path, "r");
    struct stat statbuf;
    stat(param.model_path, &statbuf);
    size_t model_size = statbuf.st_size;

    g_ChipSdk_model_bin = malloc(sizeof(char)*model_size);
    if(fp == NULL)
    {
        PRT_ERR(DEF_TAG,"open model file failed\n");
        return -1;
    }
    else
    {
        ret = fread(g_ChipSdk_model_bin, 1, model_size, fp);
        fclose(fp);
    }
    param.model_path = g_ChipSdk_model_bin;
    //printf("20230314: param.model_path = %p\n",param.model_path);
    param.model_size = model_size;
    param.ptime = false;
    param.switch_stop_det = false;
    param.fast_update_params = false;

    //周界参数配置
    param.enable_perm = false;
    param.permcnt = 3;//周界的数量
    param.mod = 0;//mod = 0:检测多边形模式

    int i,k;
    for(i = 0;i < param.permcnt;i++)
    {
        switch(i)
        {
        case 0:
        {
            param.perms[0].perm_id = 0;
            param.perms[0].pcnt=6;
            param.perms[0].p = (IVSPoint *)malloc(param.perms[0].pcnt* sizeof(IVSPoint));

            param.perms[0].p[0].x = 0;
            param.perms[0].p[0].y = 0;
            param.perms[0].p[1].x = sensor_sub_width/4;
            param.perms[0].p[1].y = 0;
            param.perms[0].p[2].x = sensor_sub_width/2;
            param.perms[0].p[2].y = 0;

            param.perms[0].p[3].x = sensor_sub_width/2;
            param.perms[0].p[3].y = sensor_sub_height-1;
            param.perms[0].p[4].x = sensor_sub_width/4;
            param.perms[0].p[4].y = sensor_sub_height-1;
            param.perms[0].p[5].x = 0;
            param.perms[0].p[5].y = sensor_sub_height-1;
        }
            break;
        case 1:
        {
            param.perms[1].perm_id = 1;
            param.perms[1].pcnt=5;
            param.perms[1].p = (IVSPoint *)malloc(param.perms[1].pcnt* sizeof(IVSPoint));

            param.perms[1].p[0].x = sensor_sub_width/2;
            param.perms[1].p[0].y = 0;

            param.perms[1].p[1].x = sensor_sub_width/4*3;
            param.perms[1].p[1].y = 0;

            param.perms[1].p[2].x = sensor_sub_width-1;
            param.perms[1].p[2].y = 0;

            param.perms[1].p[3].x = sensor_sub_width-1;
            param.perms[1].p[3].y = sensor_sub_height-1;

            param.perms[1].p[4].x = sensor_sub_width/4*3;
            param.perms[1].p[4].y = sensor_sub_height-1;
        }
            break;
        case 2:
        {
            k=2;
            param.perms[k].perm_id = 2;
            param.perms[k].pcnt=4;
            param.perms[k].p = (IVSPoint *)malloc(param.perms[k].pcnt* sizeof(IVSPoint));

            param.perms[k].p[0].x = 0;
            param.perms[k].p[0].y = 0;

            param.perms[k].p[1].x = sensor_sub_width/2;
            param.perms[k].p[1].y = 0;

            param.perms[k].p[2].x = sensor_sub_width/2;
            param.perms[k].p[2].y = sensor_sub_height-1;

            param.perms[k].p[3].x = 0;
            param.perms[k].p[3].y = sensor_sub_height-1;
        }
            break;
        }
    }

    *interface = PersonvehiclepetDetInterfaceInit(&param);
    if (*interface == NULL) {
        PRT_ERR(DEF_TAG, "IMP_IVS_CreateGroup(%d) failed\n", grp_num);
        return -1;
    }

    ret = IMP_IVS_CreateChn(chn_num, *interface);
    if (ret < 0) {
        PRT_ERR(DEF_TAG, "IMP_IVS_CreateChn(%d) failed\n", chn_num);
        return -1;
    }

    ret = IMP_IVS_RegisterChn(grp_num, chn_num);
    if (ret < 0) {
        PRT_ERR(DEF_TAG, "IMP_IVS_RegisterChn(%d, %d) failed\n", grp_num, chn_num);
        return -1;
    }

    ret = IMP_IVS_StartRecvPic(chn_num);
    if (ret < 0) {
        PRT_ERR(DEF_TAG, "IMP_IVS_StartRecvPic(%d) failed\n", chn_num);
        return -1;
    }

    PRT_INFO(DEF_TAG,"PersonvehiclepetDet init ok\n");

    return 0;
}

int ChipSdk_ivs_personvehiclepetdet_stop(int chn_num, IMPIVSInterface *interface)
{
    int ret = 0;

    ret = IMP_IVS_StopRecvPic(chn_num);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "IMP_IVS_StopRecvPic(%d) failed\n", chn_num);
        return -1;
    }
    sleep(1);

    ret = IMP_IVS_UnRegisterChn(chn_num);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "IMP_IVS_UnRegisterChn(%d) failed\n", chn_num);
        return -1;
    }

    ret = IMP_IVS_DestroyChn(chn_num);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "IMP_IVS_DestroyChn(%d) failed\n", chn_num);
        return -1;
    }

    PersonvehiclepetDetInterfaceExit(interface);

    return 0;
}

int Ext_ChipSdkIvs_PersonvehiclepetdetInit(void)
{
    int ret;

    ret = ChipSdk_ivs_personvehiclepetdet_start(0, DEF_SDK_PERSON_DETECT_CHN, &g_Sdk_PersonInterface);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "ivs personvehiclepetdet start(0, 2) failed\n");
        return -1;
    }

    return 0;
}

void Ext_ChipSdkIvs_PersonvehiclepetdetExit(void)
{
    ChipSdk_ivs_personvehiclepetdet_stop(DEF_SDK_PERSON_DETECT_CHN,g_Sdk_PersonInterface);
}

int Ext_ChipSdkIvs_GetPersonvehiclepetdetResult(void)
{
    int ret = 0;
    int i;
    personvehiclepetdet_param_output_t *result = NULL;

    ret = IMP_IVS_PollingResult(DEF_SDK_PERSON_DETECT_CHN, IMP_IVS_DEFAULT_TIMEOUTMS);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "IMP_IVS_PollingResult failed\n");
        return DEF_COM_FALSE;
    }

    ret = IMP_IVS_GetResult(DEF_SDK_PERSON_DETECT_CHN, (void **)&result);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "IMP_IVS_GetResult failed\n");
        return DEF_COM_FALSE;
    }

    int ai_detect_cnt = result->count;
    personvehiclepet_info info[ai_detect_cnt];

    //PRT_NORMAL("ai_detect_cnt: %d\n",ai_detect_cnt);
    memset(info,0,sizeof(info));
    for(i = 0; i < ai_detect_cnt; i++)
    {
        info[i].track_id = result->personvehiclepet[i].track_id;
        info[i].class_id = result->personvehiclepet[i].class_id;
        info[i].confidence = result->personvehiclepet[i].confidence;
        info[i].show_box.ul.x  = result->personvehiclepet[i].show_box.ul.x;
        info[i].show_box.ul.y  = result->personvehiclepet[i].show_box.ul.y;
        info[i].show_box.br.x  = result->personvehiclepet[i].show_box.br.x;
        info[i].show_box.br.y  = result->personvehiclepet[i].show_box.br.y;

#if 0
        PRT_DBG(DEF_TAG,"index[%d],id[%d],confidence: %f\n",i,info[i].class_id,info[i].confidence);
        PRT_DBG(DEF_TAG,"ul.x[%d],ul.y[%d],br.x[%d],br.y[%d]\n",info[i].show_box.ul.x,info[i].show_box.ul.y,info[i].show_box.br.x,info[i].show_box.br.y);
#endif
    }

    ret = IMP_IVS_ReleaseResult(DEF_SDK_PERSON_DETECT_CHN, (void *)result);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG, "IMP_IVS_ReleaseResult failed\n");
        return DEF_COM_FALSE;
    }

    for(int i = 0; i < ai_detect_cnt; i++)
    {
        if((info[i].class_id == 7) || (info[i].class_id == 8))
        {
            //PRT_DBG(DEF_TAG,"detect pet>>>>>>>>>>>>>>>>>>>>>>\n");
            if((info[i].show_box.br.y > 200) || (info[i].show_box.ul.y > 200))
            {
                return E_PET_MOTION_LITTER_BOX_CAT_ENTER;
            }
            else
            {
                return E_PET_MOTION_PET_APPEAR;
            }
        }
    }

    return DEF_COM_FALSE;
}
#endif
